﻿package fwk.sound
{
	import flash.display.MovieClip;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
	
	import flash.utils.getDefinitionByName;
	
	import flash.events.Event;
	
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	
	import gs.TweenMax;
	import gs.easing.Linear;
	
	public class CfSound
	{
		public var _manager			:CfSoundManager;
		public var _sndId			:String;
		public var _loops			:Object;
		public var _loopsCurrent	:Object;
		public var snd				:Sound;
		public var _urlSound		:String = "";
		private var channel			:SoundChannel;
		private var transform		:SoundTransform;
		
		private var _bIsPlaying		:Boolean			= false;
		private var _isMuted		:Boolean			= false;
		private var _volume			:Number				= 1;
		
		private var _classReference:Class;
		private var _isUrl:Boolean = false;
		
		public function set volume(val:Number):void
		{
			_volume = val;
			transform = new SoundTransform(_volume);
			if(channel != null) channel.soundTransform = transform;
		}
		public function get volume():Number
		{
			return _volume;
		}
		public function CfSound():void
		{
			trace("CfSound");
		}
		
		public function init(sndId:String, loop:Object = 1, isUrl:Boolean = false, mute:Boolean = false):void
		{
			trace("CfSound : init(" + sndId + ")");
			_sndId = sndId;
			_loops 			= loop;
			_loopsCurrent 	= loop;
			_isUrl = isUrl;
			
			_isMuted = mute;
				
			try{

				
				if (_isUrl) {
					_urlSound = sndId;
				}else {
					_classReference = getDefinitionByName(_sndId) as Class;
				}
				
				snd = getNewInstance();
				
				
				_bIsPlaying = false;
				transform = new SoundTransform(_volume);
				

			}catch (e) {
				trace("XXXX Le son avec le nom de liaison " + _sndId + " n'existe pas dans la librairie");
				
			}
		}
		
		function getNewInstance():Sound {
			
			trace("_isUrl " + _isUrl);
			
			var ret:Sound;
			
			if (_isUrl) {
				ret = new Sound();
				ret.addEventListener(IOErrorEvent.IO_ERROR, onErrorLoad);
				ret.load(new URLRequest(_urlSound));
				
				function onErrorLoad(evt:IOErrorEvent) {
					ret.removeEventListener(IOErrorEvent.IO_ERROR, onErrorLoad);
					trace("XXXX impossible de charger le fichier : " + _urlSound);
					snd = null;
				}
			}else {
				ret = new _classReference() as Sound;
			}
			
			return ret;
		}
		
		
		public function play(fade:Boolean = false, durationFade:Number = 1,  startTime:Number = 0, loops:Object = null):void
		{
			if(_bIsPlaying == false && snd != null)
			{
				_loopsCurrent = _loops;
				if(loops != null) _loopsCurrent = loops;
				//trace("CfSound : play(" + startTime +", " + _loopsCurrent + ") : " + _sndId);
				//trace("play " + _urlSound);
				
				
				
				if(channel != null) channel.stop();
				

				
				
				if (_loopsCurrent is Number)
				{
					// si c'est un son d'evenemnt qui se joue qu'une fois a chaque fois
					if (_loopsCurrent == 1) {
						if (!_isMuted) {
							snd = getNewInstance();
							channel = snd.play(startTime, _loopsCurrent as int, transform);
						}
					}
					else {
						_bIsPlaying = true;
						if (!_isMuted)
						{
							if (_loopsCurrent == 0) {
								channel = snd.play(startTime, 9999999, transform);
							}
							else {
								channel = snd.play(startTime, _loopsCurrent as int, transform);
								channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
							}
						}

					}

				}else if (_loopsCurrent is String && _loopsCurrent == "infinite")
				{
					_bIsPlaying = true;
					if (!_isMuted) {
						channel = snd.play(startTime, 99999999, transform);
					}
				}
				
				if (fade && _isMuted == false) {
					transform.volume = 0;
					channel.soundTransform = transform;
					fadeVolume(volume, durationFade);
				}
			}
		}
		
		public function resume():void
		{
			trace("resume " + _urlSound);
			
			if(_bIsPlaying == false && !_isMuted)
			{
				if (channel != null) {
					resumeF();
				}
				else  play();
			}
		}
		
		private function resumeF():void
		{
			try {
				trace("CfSound : resume : " + _sndId);
				trace("CHANNEL : " + channel);
				_bIsPlaying = true;
				if (channel != null) {
					trace("A ");
					var oldChannel:SoundChannel = channel;
					oldChannel.stop();
				}
				trace("B ");
				if (_loopsCurrent is Number)
				{
					trace("C ");
					if (_loopsCurrent == 0) {
						trace("C1 ");
						channel = snd.play(0, 9999999, transform);
					}
					else {
						trace("C2 ");
						channel = snd.play(0, _loopsCurrent as int, transform);
						trace("C21 ");
						trace("_loopsCurrent =  " +_loopsCurrent);
						trace("transform =  " +transform);
						trace("channel =  " +channel);
						channel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
						trace("C22 ");
					}
				}else if (_loopsCurrent is String && _loopsCurrent == "infinite")
				{
					trace("D ");
					channel = snd.play(0, 9999999, transform);
				}
				trace("E ");
			}catch (e) {
				trace("e " +e);
			}
		}
		
		public function onSoundComplete(e:Event = null):void
		{
			//trace("CfSound : onSoundComplete");
			
			_bIsPlaying = false;
		}
		
		/*public function loop(e:Event = null):void
		{
			trace("CfSound : loop");
			
			channel.stop();
			channel.removeEventListener(Event.SOUND_COMPLETE, loop);
			if (!_isMuted)
			{
				channel = snd.play(0, 0, transform);
				channel.addEventListener(Event.SOUND_COMPLETE, loop);
			}
		}*/
		
		public function mute(flag:Boolean, fade:Boolean = false, durationFade:Number = 1):void
		{
			if (_isMuted != flag)
			{
				_isMuted = flag;
				if (!_isMuted)
				{
					if ( _bIsPlaying) {
						resumeF();
						if ( fade) fadeVolume(volume, durationFade);
						else volume = _volume;
					}
				}else {
					if (_bIsPlaying) {
						if ( fade) fadeVolume(0, durationFade, true);
						else channel.stop();
					}
				}
			}
		}
		
		public function stop(fade:Boolean = false, durationFade:Number = 1):void
		{
			//trace("CfSound : stop : " + _sndId);
			
			if(channel != null)
			{
				
				if ( fade) fadeVolume(0, durationFade, true);
				else channel.stop();
			}
			
			_bIsPlaying = false;
		}
		
		public function setVolume(nVolume:Number):void
		{
			//trace("CfSound : setVolume(" + nVolume + ") : " + _sndId);
			
			try {
				transform = channel.soundTransform;
				transform.volume = nVolume;
				channel.soundTransform = transform;
			}catch (e) {
				
			}
        }
		
		public function fadeVolume(nVolume:Number, nDuration:Number, sStop:Boolean = false):void
		{
			//trace("CfSound : fadeVolume(" + nVolume + ", " + nDuration + ", " + sStop + ") : " + _sndId);
			
			
			TweenMax.killTweensOf(transform);
			
			if (!sStop)
			{
				TweenMax.to(transform, nDuration, { volume:nVolume, ease:Linear, onUpdate:onUpdateVolume } );
			}
			else
			{
				TweenMax.to(transform, nDuration, { volume:nVolume, ease:Linear, onUpdate:onUpdateVolume, onComplete:fadeStop } );

			}
		}
		
		public function fadeStop():void
		{
			channel.stop();
			
		}
		
		public function onUpdateVolume():void
		{
	
			if(channel != null)
			{
				channel.soundTransform = transform;
			}
		}
	}
}